import Preparation from '../../shared/preparation.md'
import { Tabs, Tab, PackageManagerTabs } from '@theme';

# React Multi Version

demo项目仓库 `emp`:

```bash
git clone https://github.com/empjs/emp
```

:::danger 🚨 可能遇到的错误
如果您无法拉取项目至本地，请检查您的网络环境或代理设置是否可以访问github，如果仍不能解决，请联系我们。
:::

在拉取完成代码后，我们进入代码的根目录，安装项目依赖，推荐使用`PNPM`进行安装：

<PackageManagerTabs command="install" />

安装完依赖后，运行 `demos/react16_18/react-16-app` 示例项目。

## 运行示例项目

:::warning ⚠️ 注意
在运行示例项目之前，请确保您已经完成了前期准备，并当前目录处于`emp`仓库的根目录下。
:::

### mf-host

首先进入示例项目的根目录：

```bash
cd demos/react16_18/react-16-app
```

然后运行代码：
<PackageManagerTabs command="dev" />

运行成功后，您可以访问`http://localhost:4002/`进行查看。


## 演示效果

当您的代码运行成功之后，它应该是这样子的🤩：<a target='_blank' href='https://emp-demo-react16and18.pages.dev/'>访问链接</a>

<iframe src="https://emp-demo-react16and18.pages.dev/"
  style={{width: '100%', height: '450px', border: `20px solid #aaa`, borderRadius: '4px', overflow: 'hidden'}}
  title="mf-host"
></iframe>

## 项目配置

```ts title="emp.config.ts"
import {defineConfig} from '@empjs/cli'
import pluginReact from '@empjs/plugin-react'
import {pluginRspackEmpShare} from '@empjs/share'
//
export default defineConfig((store) => {
  // react18 host 基站地址
  const mfhost = "https://emp-demo-react18-host.pages.dev/demos/react18/react-host/dist/emp.js"
  // react18 框架库地址 
  const frameworkLib = "https://unpkg.com/@empjs/libs-18@0.0.1/dist"
  return {
    plugins: [
      pluginReact(),
      pluginRspackEmpShare({
        empRuntime: {
          frameworkLib,
          frameworkGlobal: 'EMP_ADAPTER_REACT',
          framework: undefined, // 跨版本这里必须要配置为 undefined
          // 远程模块加载库运行时 moudle federation runtime
          runtimeLib: "https://unpkg.com/@empjs/share@3.1.2/output/full.js",
        },
      }),
    ],
    server: {port: 4002},
    define: {mfhost},
    debug: {clearLog: false, showRsconfig: 'x.json'},
  }
})
```

## 核心代码
```tsx title="src/App.tsx"
import React, { useEffect, useState, version } from 'react'
import ReactDOM from 'react-dom'
import { Card, CountComp as CountComp16, ShowCountComp as ShowCountComp16 } from './CountComp'
import './index.css'
import './normalize.css'
import { reactAdapter } from '@empjs/share/adapter'
import empRuntime from '@empjs/share/runtime'
const entry = process.env.mfhost as string
// 实例化远程 emp
empRuntime.init({
  shared: reactAdapter.shared,
  remotes: [
    {
      name: 'runtimeHost',
      entry,
    },
  ],
  name: 'federationRuntimeDemo',
})
// 封装 React 18的组件 以便插入到 React 16
const React18App = reactAdapter.adapter(empRuntime.load('runtimeHost/App'))

// 封装 React 16的组件 以便插入到 React 18
const ParentComponentAdepter = reactAdapter.adapter(CountComp16, 'default', React, ReactDOM)

const App = () => {
  return (
    <>
      <h1>App React Version {version}</h1>
      <ShowCountComp16 />
      <Card title="EMP From mfhost">
        <React18App>
          <ParentComponentAdepter />
        </React18App>
      </Card>
    </>
  )
}
export default App

```

:::tip
更多详情见 [pluginRspackEmpShare](/plugin/tool/share) 插件配置。
:::